/*
 * 实现客户端的RPC调用
 */
#pragma once
#include "requestor.hpp"

namespace jsonrpc
{
    namespace client
    {
        class RpcCaller
        {
        public:
            using ptr = std::shared_ptr<RpcCaller>;
            using JsonAsyncResponse = std::future<Json::Value>;
            using JsonResponseCallback = std::function<void(const Json::Value &)>;
            RpcCaller(const Requestor::ptr &req) : requestor(req) {}

        public:
            // 同步调用（阻塞等待），结果通过 result 引用返回。
            bool call(const BaseConnection::ptr &conn, const std::string &method,
                      const Json::Value &params, Json::Value &result)
            {
                LOG_DEBUG("Sync RPC call start, method:%s", method.c_str());
                // 组织请求
                auto req_msg = MessageFactory::create<RpcRequest>();
                req_msg->setRid(UUIDUtil::generateUUID());
                req_msg->setMessageType(MType::REQ_RPC);
                req_msg->setMethod(method);
                req_msg->setParams(params);
                // 发送请求
                BaseMessage::ptr rsp_msg;
                if (!requestor->send(conn, std::dynamic_pointer_cast<BaseMessage>(req_msg), rsp_msg))
                {
                    LOG_ERROR("RPC sync request send failed!");
                    return false;
                }
                LOG_DEBUG("RPC sync request send success,start parse");
                // 等待响应
                auto rpc_rsp_msg = std::dynamic_pointer_cast<RpcResponse>(rsp_msg);
                if (!rpc_rsp_msg)
                {
                    LOG_ERROR("RPC response type conversion failed!");
                    return false;
                }
                if (rpc_rsp_msg->getRCode() != RCode::RCODE_OK)
                {
                    LOG_ERROR("RPC sync request error:%s", errReason(rpc_rsp_msg->getRCode()));
                    return false;
                }
                result = rpc_rsp_msg->getResult();
                LOG_DEBUG("Sync RPC call end, method:%s", method.c_str());
                return true;
            }
            // 异步调用（非阻塞），结果通过 future.get() 获取。
            bool call(const BaseConnection::ptr &conn, const std::string &method,
                      const Json::Value &params, JsonAsyncResponse &result)
            {
                // 组织请求
                auto req_msg = MessageFactory::create<RpcRequest>();
                req_msg->setRid(UUIDUtil::generateUUID());
                req_msg->setMessageType(MType::REQ_RPC);
                req_msg->setMethod(method);
                req_msg->setParams(params);

                auto json_promise = std::make_shared<std::promise<Json::Value>>();
                result = json_promise->get_future();

                Requestor::RequestCallback cb = std::bind(&RpcCaller::HandleAsyncFutureResult, this, json_promise, std::placeholders::_1);
                if (!requestor->send(conn, std::dynamic_pointer_cast<BaseMessage>(req_msg), cb))
                {
                    LOG_ERROR("RPC async request send failed!");
                    return false;
                }
                return true;
            }
            // 回调调用（非阻塞），结果通过用户传入的回调函数 cb 处理。
            bool call(const BaseConnection::ptr &conn, const std::string &method,
                      const Json::Value &params, const JsonResponseCallback &cb)
            {
                // 组织请求
                auto req_msg = MessageFactory::create<RpcRequest>();
                req_msg->setRid(UUIDUtil::generateUUID());
                req_msg->setMessageType(MType::REQ_RPC);
                req_msg->setMethod(method);
                req_msg->setParams(params);

                Requestor::RequestCallback req_cb = std::bind(&RpcCaller::InvokeUserCallback, this, cb, std::placeholders::_1);
                if (!requestor->send(conn, std::dynamic_pointer_cast<BaseMessage>(req_msg), req_cb)){
                    LOG_ERROR("RPC callback request send failed!");
                    return false;
                }
                return true;
            }

        private:
            // 处理 ​​异步 Future/Promise 模式​​ 的 RPC 响应，将结果存入 std::promise，供调用方通过 future.get() 获取。
            void HandleAsyncFutureResult(std::shared_ptr<std::promise<Json::Value>> result_promise,
                                         const BaseMessage::ptr &msg)
            {
                auto rpc_rsp_msg = std::dynamic_pointer_cast<RpcResponse>(msg);
                if (!rpc_rsp_msg)
                {

                    LOG_ERROR("RPC response type conversion failed!");
                    return;
                }
                if (rpc_rsp_msg->getRCode() != RCode::RCODE_OK)
                {
                    LOG_ERROR("RPC  async request error:%s", errReason(rpc_rsp_msg->getRCode()));
                    return;
                }
                result_promise->set_value(rpc_rsp_msg->getResult()); // 设置 future 的结果
            }
            // 处理 ​​回调模式​​ 的 RPC 响应，直接调用用户传入的回调函数 user_callback。
            void InvokeUserCallback(const JsonResponseCallback &user_callback,
                                    const BaseMessage::ptr &msg)
            {
                auto rpc_rsp_msg = std::dynamic_pointer_cast<RpcResponse>(msg);
                if (!rpc_rsp_msg)
                {
                    LOG_ERROR("RPC response type conversion failed!");
                    return;
                }
                if (rpc_rsp_msg->getRCode() != RCode::RCODE_OK)
                {
                    LOG_ERROR("RPC callback request error:%s", errReason(rpc_rsp_msg->getRCode()));
                    return;
                }
                user_callback(rpc_rsp_msg->getResult()); // 直接调用用户回调
            }

        private:
            Requestor::ptr requestor;
        };
    }
}